#pragma once

#include <src/miscellaneous/stat/Analyzer_Performance.h>
#include <src/math/functor/GaussianFunctor.h>
#include <src/math/Operators/delta_particle.h>

template <class data, std::size_t Dim = data::Dim>
struct Fill_Data {
	data operator()()
	{
		STATIC_CHECK(false); // to implement
	};
};
template <class data>
struct Fill_Data<data,1> {
	data operator()()
	{
#if defined(_DEBUG) // a small array just for debug purposes
	return InverseCumulativeFunctor<data>()(10);
 #else
	return InverseCumulativeFunctor<data>()(10000);
#endif
	};
};
template <class data>
struct Fill_Data<data,2> {
	data operator()()
	{
#if defined(_DEBUG) // a small array just for debug purposes
	return InverseCumulativeFunctor<data>()(10,2);
 #else
	return InverseCumulativeFunctor<data>()(10000,2);
#endif
	};
};


template<class operator1, class operator2>
struct operator_Performance_Analyzer
{
	void operator()() 
	{
		typedef typename operator1::argument_base_type data1;
		typedef typename operator2::argument_base_type data2;
		std::cout << std::endl << "----data_Performance_Analyzer---------------------" << std::endl ;
		std::cout << std::endl << "----comparaison between" << data1::get_name() <<"  and "<<data2::get_name() <<" ---------------------" << std::endl ;



		data1 test1 = Fill_Data<data1>()();
		operator1 Op1;
		Op1.set_state_variable(smart_ptr<data1> (new data1(test1)) );


		data2 test2 = Fill_Data<data2>()();
		operator2 Op2;
		Op2.set_state_variable(smart_ptr<data2> (new data2(test2)) );

		std::cout << std::endl << "----compare performance of the operator --------" << operator1::get_name()<< " and "<< operator2::get_name() << std::endl ;
		std::cout << std::endl << "----with datas--------" << data1::get_name()<< " and "<< data2::get_name() << std::endl ;
		{
			Analyzer_Timer begin_loop("begin loop for both Operators");
			{
				Analyzer_Timer timer("loop operator 1");
				for (OS_size i = 0; i < 100; ++i) {
					if (i % 10 == 0) std::cout << i;
					Op1(test1);
				};
			};
			{
				Analyzer_Timer timer("loop operator 2");
				for (OS_size i = 0; i < 100; ++i) {
					if (i % 10 == 0) std::cout << i;
					Op2(test2);
				};
			};
			begin_loop.end();
			std::cout << begin_loop;
			begin_loop.clear();
		};
		std::cout << std::endl << "----ended. hit a key to finish--------" << std::endl ;
		std::string null;

#if !defined(_DEBUG) // the debug mode has no sense for performance
		std::cin >> null;
#endif
	};
};

void operator_Performance_test();
